﻿using System.Linq;
using CID.Domain.Infrastructure;
using CID.Tests.Support;
using NUnit.Framework;

namespace CID.Domain.Persistence.Tests.Infrastructure
{
    [TestFixture]
    class PackageTypePersistenceTests : BasePersistenceWithDataTests
    {
        private static void AssertAreEqual(PackageType expected, PackageType actual)
        {
            Assert.AreEqual(expected.Id, actual.Id);
            Assert.AreEqual(expected.Name, actual.Name);
            Assert.AreEqual(expected.Description, actual.Description);
            Assert.AreEqual(expected.Enabled, actual.Enabled);
            CollectionAssert.AreEquivalent(expected.Packages.Select(x => x.Id), actual.Packages.Select(x => x.Id));
        }

        [Test]
        public void SaveNewPackageType_PackageTypeShouldBeSaved()
        {
            var session = OpenSession();
            var newPackageType = DataProvider.CreatePackageType();
            session.SaveOrUpdate(newPackageType);
            CleanSession(session);

            Assert.AreNotEqual(NotSavedId, newPackageType.Id);
            session = OpenSession();
            var retrievedPackageType = session.Get<PackageType>(newPackageType.Id);
            AssertAreEqual(newPackageType, retrievedPackageType);
            CleanSession(session);
        }

        [Test]
        public void SaveModifiedPackageType_ChangesShouldBeSaved()
        {
            var session = OpenSession();
            var newPackageType = DataProvider.CreatePackageType();
            var newPackage = newPackageType.CreatePackage(Development.DataProvider.GetVersion(session, DevelopmentData.Component1UnreleasedVersion), new byte[] { 1, 2, 3 }, "Some comment");
            session.SaveOrUpdate(newPackageType);
            CleanSession(session);

            session = OpenSession();
            var modifiedPackageType = session.Get<PackageType>(newPackageType.Id);
            AssertAreEqual(newPackageType, modifiedPackageType); //Necessary to load lazy collections before the session is wiped out
            modifiedPackageType.ModifyProperty(x => x.Name);
            modifiedPackageType.ModifyProperty(x => x.Description);
            var version = Development.DataProvider.GetVersion(session, DevelopmentData.Component2UnreleasedVersion);
            modifiedPackageType.CreatePackage(version, new byte[] { 3, 2, 1}, "Another comment");
            modifiedPackageType.ModifyProperty(x => x.Enabled);
            session.SaveOrUpdate(modifiedPackageType);
            CleanSession(session);

            session = OpenSession();
            var retrievedPackageType = session.Get<PackageType>(newPackageType.Id);
            AssertAreEqual(modifiedPackageType, retrievedPackageType);
            CleanSession(session);
        }

        [Test]
        public void DeletePackageType_PackageTypeShouldBeDeleted()
        {
            var session = OpenSession();
            var newPackageType1 = DataProvider.CreatePackageType("Another PackageType Name");
            var newPackageType2 = DataProvider.CreatePackageType();
            session.SaveOrUpdate(newPackageType1);
            session.SaveOrUpdate(newPackageType2);
            CleanSession(session);

            session = OpenSession();
            var retrievedPackageType1 = session.Get<PackageType>(newPackageType1.Id);
            session.Delete(retrievedPackageType1);
            CleanSession(session);

            session = OpenSession();
            retrievedPackageType1 = session.Get<PackageType>(newPackageType1.Id);
            var retrievedPackageType2 = session.Get<PackageType>(newPackageType2.Id);
            Assert.IsNull(retrievedPackageType1);
            Assert.IsNotNull(retrievedPackageType2);
            CleanSession(session);
        }
    }
}
